﻿using Logistics.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MyAlipay.Demo;
using NLog;
using System;
using System.Collections.Generic;

using Aop.Api.Util;
using Aop.Api.Domain;
using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;

namespace Logistics.Web.Controllers
{
    public class PayController : Controller
    {
        private readonly Logger logger = LogManager.GetCurrentClassLogger();

        // GET: Pay
        public ActionResult Index(int id,string name)
        {
            ViewBag.Id = id;
            ViewBag.Name = name;
            logger.Info($" 进入支付页面！");
            return View();
        }

        public ActionResult DivIndex()
        {
            return View();
        }

        /// <summary>
        /// 支付宝支付
        /// </summary>
        /// <param name="tradeNo">商户订单号</param>
        /// <param name="subject">订单名称</param>
        /// <param name="totaAamount">付款金额</param>
        /// <param name="body">商品描述</param>
        /// <returns></returns>
        public IActionResult AlipaySubmit(string tradeNo, string subject, string totalAmount, string body)
        {
            logger.Info($" 进入支付方法！");

            DefaultAopClient client = new DefaultAopClient(AlipayConfig.GatewayUrl, AlipayConfig.AppId, AlipayConfig.PrivateKey, "json", "2.0", AlipayConfig.SignType, AlipayConfig.AlipayPublicKey, AlipayConfig.CharSet, false);

            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            model.Body = body.Trim();// 商品描述
            model.Subject = subject.Trim();// 订单名称
            model.TotalAmount = totalAmount.Trim(); // 付款金额
            model.OutTradeNo = tradeNo.Trim();// 订  单号
            model.ProductCode = "FAST_INSTANT_TRADE_PAY";
            DapperHelper.AddOrder(model);

            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            request.SetReturnUrl(Request.GetHostUri() + "/Pay/ReturnUrl");// 设置同步回调地址
            request.SetNotifyUrl(Request.GetHostUri() + "/Pay/NotifyUrl");// 设置异步接收通知地址
            request.SetBizModel(model);
            AlipayTradePagePayResponse response = null;
            try
            {
                logger.Info($" 开始跳转到支付页面！");
                response = client.pageExecute(request, null, "post");
            }
            catch (Exception ex)
            {
                logger.Error($" 支付报错：" + ex.Message);
                return Json(new { Result = false, FormData = ex.Message });
            }
            logger.Info($"组装的支付Form数据：" + response.Body);
            return Json(new { Result = true, FormData = response.Body });
        }

        /// <summary>
        /// 同步回调函数,由支付宝客户端重定向用户浏览器实现 
        /// </summary>
        /// <returns></returns>
        public ActionResult ReturnUrl()
        {
            logger.Info($" 支付完成，进入同步回调函数页面！");

            var sPara = new Dictionary<string, string>();
            var requestItem = Request.Query.Keys;
            if (requestItem != null)
            {
                foreach (string key in requestItem)
                {
                    Microsoft.Extensions.Primitives.StringValues tmpVal = "";
                    Request.Query.TryGetValue(key, out tmpVal);
                    sPara.Add(key, tmpVal);
                }
            }

            if (sPara.Count > 0)
            {
                //同步验证
                logger.Info($" 同步验证开始！");
                bool flag = AlipaySignature.RSACheckV1(sPara, AlipayConfig.AlipayPublicKey, AlipayConfig.CharSet, AlipayConfig.SignType, false);
                if (flag)
                {
                    logger.Info($" 同步验证通过！");
                    var paraJson = Newtonsoft.Json.JsonConvert.SerializeObject(sPara);

                    //获取支付宝的通知返回参数
                    var alipayReturnInfo = new AlipayReturnInfo();
                    alipayReturnInfo.Remarks = "同步方法：ReturnUrl,返回值：" + paraJson;
                    alipayReturnInfo.Charset = GetValueByKey(sPara, "charset");
                    alipayReturnInfo.OutTradeNo = GetValueByKey(sPara, "out_trade_no");
                    alipayReturnInfo.Method = GetValueByKey(sPara, "method");
                    alipayReturnInfo.TotalAccount = GetValueByKey(sPara, "total_amount");
                    alipayReturnInfo.TradeNo = GetValueByKey(sPara, "trade_no");
                    alipayReturnInfo.AuthAppId = GetValueByKey(sPara, "auth_app_id");
                    alipayReturnInfo.Version = GetValueByKey(sPara, "version");
                    alipayReturnInfo.AppId = GetValueByKey(sPara, "app_id");
                    alipayReturnInfo.SellerId = GetValueByKey(sPara, "seller_id");
                    alipayReturnInfo.TimeStamp = GetValueByKey(sPara, "timestamp");

                    logger.Info($" 开始插入数据库数据！");
                    DapperHelper.UpdateOrderStatus(alipayReturnInfo.OutTradeNo, alipayReturnInfo.TotalAccount, 1);
                    var i = DapperHelper.AddPayReturnUrl(alipayReturnInfo);
                    var msg = i > 0 ? "支付成功，状态修改成功！" : "支付成功，状态修改失败！";
                    ViewBag.PayFlag = i;
                    ViewBag.PayStatus = msg;
                    logger.Info(msg);
                }
                else
                {
                    logger.Info($" 同步验证失败！");
                    var outTradeNo = GetValueByKey(sPara, "out_trade_no");
                    var totalAccount = GetValueByKey(sPara, "total_amount");
                    DapperHelper.UpdateOrderStatus(outTradeNo, totalAccount, 2);
                }
            }

            return View();
        }

        /// <summary>
        /// 异步：通信异常或中断时回调函数,支付宝后台调用
        /// </summary>
        /// <returns></returns>
        public ActionResult NotifyUrl()
        {
            logger.Info($" 支付完成，进入异步回调函数页面！");

            var sPara = new Dictionary<string, string>();
            var requestItem = Request.Query.Keys;
            if (requestItem != null)
            {
                foreach (string key in requestItem)
                {
                    Microsoft.Extensions.Primitives.StringValues tmpVal = "";
                    Request.Query.TryGetValue(key, out tmpVal);
                    sPara.Add(key, tmpVal);
                }
            }

            if (sPara.Count > 0) //判断是否有带返回参数
            {
                //异步验证
                logger.Info($" 异步验证开始！");
                bool flag = AlipaySignature.RSACheckV1(sPara, AlipayConfig.AlipayPublicKey, AlipayConfig.CharSet, AlipayConfig.SignType, false);
                if (flag)
                {
                    logger.Info($" 异步验证通过！");
                    var paraJson = Newtonsoft.Json.JsonConvert.SerializeObject(sPara);

                    //获取支付宝的通知返回参数
                    var alipayReturnInfo = new AlipayReturnInfo();
                    alipayReturnInfo.Remarks = "异步方法：ReturnUrl,返回值：" + paraJson;
                    alipayReturnInfo.Charset = GetValueByKey(sPara, "charset");
                    alipayReturnInfo.OutTradeNo = GetValueByKey(sPara, "out_trade_no");
                    alipayReturnInfo.Method = GetValueByKey(sPara, "method");
                    alipayReturnInfo.TotalAccount = GetValueByKey(sPara, "total_amount");
                    alipayReturnInfo.TradeNo = GetValueByKey(sPara, "trade_no");
                    alipayReturnInfo.AuthAppId = GetValueByKey(sPara, "auth_app_id");
                    alipayReturnInfo.Version = GetValueByKey(sPara, "version");
                    alipayReturnInfo.AppId = GetValueByKey(sPara, "app_id");
                    alipayReturnInfo.SellerId = GetValueByKey(sPara, "seller_id");
                    alipayReturnInfo.TimeStamp = GetValueByKey(sPara, "timestamp");

                    logger.Info($" 开始插入数据库数据！");
                    DapperHelper.UpdateOrderStatus(alipayReturnInfo.OutTradeNo, alipayReturnInfo.TotalAccount, 1);
                    var i = DapperHelper.AddPayReturnUrl(alipayReturnInfo);
                    var msg = i > 0 ? "支付成功，状态修改成功！" : "支付成功，状态修改失败！";
                    ViewBag.PayStatus = msg;
                    logger.Info(msg);
                }
                else
                {
                    logger.Info($" 异步验证失败！");
                    var outTradeNo = GetValueByKey(sPara, "out_trade_no");
                    var totalAccount = GetValueByKey(sPara, "total_amount");
                    DapperHelper.UpdateOrderStatus(outTradeNo, totalAccount, 2);
                }
            }

            return View();
        }

        /// <summary>
        /// 通过Dictionary key值获取对应value
        /// </summary>
        public string GetValueByKey(Dictionary<string, string> dic, string key)
        {
            string result = "";
            foreach (KeyValuePair<string, string> kvp in dic)
            {
                if (kvp.Key.Equals(key))
                {
                    result = kvp.Value;
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 检查是否支付成功
        /// </summary>
        /// <param name="tradeNo">商户订单号</param>
        /// <param name="subject">订单名称</param>
        /// <param name="totaAamount">付款金额</param>
        /// <param name="body">商品描述</param>
        /// <returns></returns>
        public IActionResult CheckPaymen(string tradeNo, string totaAamount)
        {
            logger.Info($"验证是否支付完成！");

            var status = DapperHelper.CheckPaymen(tradeNo, totaAamount);
            logger.Info($"验证支付结果：tradeNo=" + tradeNo + "； totaAamount=" + totaAamount + "；支付状态：" + status);
            return Json(new { Result = true, status = status });
        }
    }
}
